/*
 * Copyright (c) 2021 HPMicro
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "board.h"                     // 开发板支持包
#include "hpm_clock_drv.h"            // 时钟驱动
#include "hpm_uart_drv.h"             // UART 驱动
#include "hpm_mcan_drv.h"             // MCAN 驱动
//#include "hpm_spi_drv.h"              // SPI 驱动
#include "hpm_clock_drv.h"            // 时钟驱动（重复包含，可优化）
#include "uart.h"
//#include "spi.h"
#include "can.h"


#define USE_CANFD 0  // 1 = 使用CANFD, 0 = 使用经典CAN

// UART 相关定义
#define TEST_UART_MAX_BUFFER_SIZE (20)  // UART 缓冲区大小
ATTR_PLACE_AT_NONCACHEABLE uint8_t data_buff[TEST_UART_MAX_BUFFER_SIZE];  // 非缓存区数据缓冲区
uint8_t buff_index;               // 缓冲区索引
uint8_t data_count;               // 数据计数

// 在文件顶部添加 UART2 的定义
#define TEST_UART2              HPM_UART2
#define TEST_UART2_IRQ          IRQn_UART2
#define TEST_UART2_CLK_NAME     clock_uart2

// 在文件顶部添加 UART5 的定义
#define TEST_UART5              HPM_UART5
#define TEST_UART5_IRQ          IRQn_UART5
#define TEST_UART5_CLK_NAME     clock_uart5

// 在文件顶部添加 UART4 的定义
#define TEST_UART4              HPM_UART4
#define TEST_UART4_IRQ          IRQn_UART4
#define TEST_UART4_CLK_NAME     clock_uart4

// 在文件顶部添加 UART7 的定义
#define TEST_UART7              HPM_UART7
#define TEST_UART7_IRQ          IRQn_UART7
#define TEST_UART7_CLK_NAME     clock_uart7



void board_init_console1(void)
{

    console_config_t cfg2;
    console_config_t cfg5;
    console_config_t cfg4;
    console_config_t cfg7;
    init_uart_pins((UART_Type *) HPM_UART2);
    init_uart_pins((UART_Type *) HPM_UART5);
    init_uart_pins((UART_Type *) HPM_UART4);
    init_uart_pins((UART_Type *) HPM_UART7);
    /* Configure the UART clock to 24MHz */
    clock_set_source_divider(clock_uart2, clk_src_pll0_clk0, 1U);
    clock_set_source_divider(clock_uart5, clk_src_pll0_clk0, 1U);
    clock_set_source_divider(clock_uart4, clk_src_pll0_clk0, 1U);
    clock_set_source_divider(clock_uart7, clk_src_pll0_clk0, 1U);

    clock_add_to_group(clock_uart2, 0);
    clock_add_to_group(clock_uart5, 0);
    clock_add_to_group(clock_uart4, 0);
    clock_add_to_group(clock_uart7, 0);

    cfg2.type = BOARD_CONSOLE_TYPE;
    cfg2.base = (uint32_t) HPM_UART2;
    cfg5.type = BOARD_CONSOLE_TYPE;
    cfg5.base = (uint32_t) HPM_UART5;
    cfg4.type = BOARD_CONSOLE_TYPE;
    cfg4.base = (uint32_t) HPM_UART4;
    cfg7.type = BOARD_CONSOLE_TYPE;
    cfg7.base = (uint32_t) HPM_UART7;

    cfg2.src_freq_in_hz = clock_get_frequency(clock_uart2);
    cfg2.baudrate = 2000000UL;
    cfg5.src_freq_in_hz = clock_get_frequency(clock_uart5);
    cfg5.baudrate = 2000000UL;
    cfg4.src_freq_in_hz = clock_get_frequency(clock_uart4);
    cfg4.baudrate = 2000000UL;
    cfg7.src_freq_in_hz = clock_get_frequency(clock_uart7);
    cfg7.baudrate = 2000000UL;
    if (status_success != console_init(&cfg2)) {
        /* failed to  initialize debug console */
        while (1) {
        }
    }
    if (status_success != console_init(&cfg5)) {
        /* failed to  initialize debug console */
        while (1) {
        }
    }
    if (status_success != console_init(&cfg4)) {
        /* failed to  initialize debug console */
        while (1) {
        }
    }
    if (status_success != console_init(&cfg7)) {
        /* failed to  initialize debug console */
        while (1) {
        }
    }
}




void init_uart(UART_Type *uart, clock_name_t clk) {
    uart_config_t config = {0};
    uart_default_config(uart, &config);
    config.src_freq_in_hz = clock_get_frequency(clk);
    uart_init(uart, &config);
}


/* CAN 通道配置结构体 */
typedef struct {
    uint8_t channel;
    MCAN_Type *base;
    mcan_config_t config;
    mcan_filter_elem_t filters[16];
} can_channel_config_t;


// 初始化CAN通道函数
hpm_stat_t init_can_channel(can_channel_config_t *can_cfg, uint32_t clock_freq)
{
    // 获取CAN控制器的默认配置
    mcan_get_default_config(can_cfg->base, &can_cfg->config);
    
    // 设置CAN总线波特率为1Mbps (1000000 bits/s)
    can_cfg->config.baudrate = 1000000;
    // 设置CAN工作模式为正常模式（非监听/回环）
    can_cfg->config.mode = mcan_mode_normal;
    
    // 配置过滤器 - 准备第一个过滤器
    uint32_t filter_count = 0;  // 过滤器计数器清零
    
    // 设置过滤器类型为经典过滤器（标准ID过滤器）
    can_cfg->filters[filter_count].filter_type = MCAN_FILTER_TYPE_CLASSIC_FILTER;
    // 配置过滤行为：匹配时存入RX FIFO 0
    can_cfg->filters[filter_count].filter_config = MCAN_FILTER_ELEM_CFG_STORE_IN_RX_FIFO0_IF_MATCH;
    // 设置过滤的CAN ID类型为标准ID（11位）
    can_cfg->filters[filter_count].can_id_type = MCAN_CAN_ID_TYPE_STANDARD;
    // 设置非同步消息（通常用于CAN FD，经典CAN设为0）
    can_cfg->filters[filter_count].sync_message = 0;
    // 增加过滤器计数
    filter_count++;
    
    // 应用过滤器配置到CAN控制器
    
    // 扩展ID过滤器列表：禁用扩展ID过滤（元素计数设为0）
    can_cfg->config.all_filters_config.ext_id_filter_list.mcan_filter_elem_count = 0;
    // 标准ID过滤器列表：指向我们配置的过滤器数组
    can_cfg->config.all_filters_config.std_id_filter_list.filter_elem_list = can_cfg->filters;
    // 标准ID过滤器列表：设置过滤器数量
    can_cfg->config.all_filters_config.std_id_filter_list.mcan_filter_elem_count = filter_count;
    
    // 全局过滤器配置：
    // 拒绝远程标准帧（不接收远程帧）
    can_cfg->config.all_filters_config.global_filter_config.reject_remote_std_frame = true;
    // 拒绝远程扩展帧（不接收扩展ID的远程帧）
    can_cfg->config.all_filters_config.global_filter_config.reject_remote_ext_frame = true;
    
    // 配置中断设置
    
    // 设置要启用的中断事件：接收和发送事件
    uint32_t interrupt_mask = MCAN_EVENT_RECEIVE | MCAN_EVENT_TRANSMIT;
    // 设置所有发送缓冲区的中断掩码（~0UL表示所有位都置1，启用所有发送中断）
    can_cfg->config.txbuf_trans_interrupt_mask = ~0UL;
    // 设置全局中断掩码
    can_cfg->config.interrupt_mask = interrupt_mask;
    
    // 使用配置初始化CAN通道
    // 参数：CAN基地址、配置结构体、时钟频率
    return mcan_init(can_cfg->base, &can_cfg->config, clock_freq);
}


/* CANFD初始化函数 */
hpm_stat_t board_init_canfd(MCAN_Type *ptr)
{
    board_init_can(ptr);
    uint32_t can_src_clk_freq = board_init_can_clock(ptr);

    mcan_config_t can_config;
    mcan_get_default_config(ptr, &can_config);
    can_config.use_lowlevel_timing_setting = true;
    
    uint16_t prescaler, prescaler_fd;
    if (can_src_clk_freq == 40000000UL) {
        prescaler = 1;
        prescaler_fd = 1;
    } else if (can_src_clk_freq == 80000000UL) {
        prescaler = 2;
        prescaler_fd = 2;
    } else {
        printf("Unsupported clock frequency for the CAN-FD test");
        return status_fail;
    }

    /* CAN Baudrate = 1Mbps (仲裁段) */
    uint16_t seg1 = 29, seg2 = 10, sjw = 2;
    /* CAN baudrate = 2Mbps (数据段) */
    uint16_t seg1_fd = 14, seg2_fd = 5, sjw_fd = 2;
    //uint16_t seg1_fd = 2, seg2_fd = 1 , sjw_fd = 2;
    can_config.can_timing.prescaler = prescaler;
    can_config.can_timing.num_seg1 = seg1;
    can_config.can_timing.num_seg2 = seg2;
    can_config.can_timing.num_sjw = sjw;

    can_config.canfd_timing.prescaler = prescaler_fd;
    can_config.canfd_timing.num_seg1 = seg1_fd;
    can_config.canfd_timing.num_seg2 = seg2_fd;
    can_config.canfd_timing.num_sjw = sjw_fd;

#ifdef CANFD_ENABLE_TRANSMITTER_DELAY_COMPENSATION
    can_config.canfd_timing.enable_tdc = true;
    can_config.tdc_config.ssp_offset = seg1_fd + 1;
    can_config.tdc_config.filter_window_length = can_config.tdc_config.ssp_offset;
#else
    can_config.canfd_timing.enable_tdc = false;
#endif

    can_config.enable_canfd = true;
    can_config.enable_tdc = can_config.canfd_timing.enable_tdc;
    can_config.mode = mcan_mode_normal;
    mcan_get_default_ram_config(ptr, &can_config.ram_config, true);//



    // 添加缺失的CANFD中断配置 - 关键修复
    uint32_t interrupt_mask = 
        MCAN_EVENT_RECEIVE | 
        MCAN_EVENT_TRANSMIT | 
        MCAN_EVENT_ERROR |
        MCAN_INT_RXFIFO0_NEW_MSG;
    
    can_config.txbuf_trans_interrupt_mask = ~0UL;
    can_config.interrupt_mask = interrupt_mask;





    
    return mcan_init(ptr, &can_config, can_src_clk_freq);
}



void send_uart_data_to_can(uint8_t* data, uint16_t data_len, uint16_t start_id, uint8_t channel)
{
  uint16_t total_frames = (data_len + 7) / 8;

  for (uint16_t frame = 0; frame < total_frames ;frame++){
    uint16_t offset = frame * 8;
    uint8_t chunk_size = (data_len - offset > 8) ?8 :(data_len - offset);

    if(chunk_size == 0) break;

    bool send_ok;
    send_data_to_can_with_id(data+offset, chunk_size, start_id +frame, channel ,&send_ok);
    //board_delay_us(50); 
  

  
  }

}

void send_uart_data_to_canfd(uint8_t* data, uint32_t data_len, uint32_t start_id, uint8_t channel)
{
    // CANFD单帧最大64字节
    uint32_t max_fd_frame_size = 64;
    uint32_t offset = 0;
    uint32_t frame_id = start_id;
    
    while (offset < data_len) {
        // 计算当前帧数据长度
        uint32_t chunk_size = (data_len - offset > max_fd_frame_size) 
                              ? max_fd_frame_size 
                              : data_len - offset;
        
        bool send_ok;
        send_data_to_canfd_with_id(data + offset, chunk_size, frame_id++, channel, &send_ok);
        
        // 错误处理（可选）
        if (!send_ok) {
            // 添加错误处理逻辑，如重试或记录错误
        }
        
        offset += chunk_size;
        
        // 小延迟避免总线拥塞
        board_delay_us(20);
    }
}
//前2字节：CAN ID（小端模式）

//第3字节：CAN 通道号

//后续字节：原始数据



// 定义UART接收数据结构体
typedef struct {
    uint8_t rx_buffer[512];
    uint16_t rx_index;
} uart_rx_data_t;

// 为每个UART实例创建独立的数据结构
static uart_rx_data_t uart2_data = {0};
static uart_rx_data_t uart5_data = {0};

static uart_rx_data_t uart4_data = {0};
static uart_rx_data_t uart7_data = {0};

 //通用UART中断处理函数
static void uart_generic_isr(UART_Type *uart, uart_rx_data_t *rx_data) {
    uint8_t irq_id = uart_get_irq_id(uart);
    
    if (irq_id == uart_intr_id_rx_data_avail) {
        while (uart_check_status(uart, uart_stat_data_ready)) {
            uint8_t byte = uart_read_byte(uart);
            
            if (byte != '\n' && rx_data->rx_index < sizeof(rx_data->rx_buffer)) {
                rx_data->rx_buffer[rx_data->rx_index++] = byte;
            }
            
            if (byte == '\n' || rx_data->rx_index >= sizeof(rx_data->rx_buffer)) {
                if (rx_data->rx_index >= 3) {
                    uint16_t frame_id = (uint16_t)rx_data->rx_buffer[1] << 8 | rx_data->rx_buffer[0];
                    uint8_t channel = rx_data->rx_buffer[2];
                    uint16_t data_len = rx_data->rx_index - 3;
                #if USE_CANFD
                    send_uart_data_to_canfd(rx_data->rx_buffer + 3, data_len, frame_id, channel);
                #else
                    send_uart_data_to_can(rx_data->rx_buffer + 3, data_len, frame_id, channel);
                #endif
   
                }
                rx_data->rx_index = 0;
            }
        }
        uart_enable_irq(uart, uart_intr_rx_data_avail_or_timeout);
    }
}

// UART4中断服务函数
void uart2_isr(void) {
    uart_generic_isr(TEST_UART2, &uart5_data);
}

// UART7中断服务函数
void uart5_isr(void) {
    uart_generic_isr(TEST_UART5, &uart5_data);
}
void uart4_isr(void) {
    uart_generic_isr(TEST_UART4, &uart4_data);
}

// UART7中断服务函数
void uart7_isr(void) {
    uart_generic_isr(TEST_UART7, &uart7_data);
}

// 中断向量声明

SDK_DECLARE_EXT_ISR_M(TEST_UART2_IRQ, uart2_isr)
SDK_DECLARE_EXT_ISR_M(TEST_UART5_IRQ, uart5_isr)
SDK_DECLARE_EXT_ISR_M(TEST_UART4_IRQ, uart4_isr)
SDK_DECLARE_EXT_ISR_M(TEST_UART7_IRQ, uart7_isr)



void uart_send_string(UART_Type *uart_ptr, const char *str)
{
    // 添加调试输出
    printf("[DEBUG] Sending to UART@%p: %s\n", (void*)uart_ptr, str);
    
    // 计算字符串长度
    uint32_t len = 0;
    const char *p = str;
    while (*p++) len++;
    
    // 发送字符串
    hpm_stat_t status = uart_send_data(uart_ptr, (uint8_t *)str, len);
    
    // 检查发送状态
    if (status != status_success) {
        printf("[ERROR] UART send failed: %d\n", status);
    }
}






// 定义CAN通道与UART端口的映射关系（根据实际硬件调整）
UART_Type* can_channel_to_uart(uint8_t can_channel) {
    switch (can_channel) {
        case 0: return HPM_UART5;  // CAN通道1 → UART5
        case 6: return HPM_UART2;  // CAN通道2 → UART2
        case 3: return HPM_UART4;  // CAN通道3 → UART4
        case 4: return HPM_UART7;  // CAN通道4 → UART7
        default: return HPM_UART0; // 默认UART（可选）
    }
}




void output_can_message(uint8_t channel, uint32_t id, uint8_t dlc, uint8_t *data, const char *source) 
{
    char buffer[128];
    int len = snprintf(buffer, sizeof(buffer), "CAN%d %s: ID=0x%03X, DLC=%d, Data=", 
                      channel, source, id, dlc);
    
    // 添加数据部分
    for (int j = 0; j < dlc; j++) {
        len += snprintf(buffer + len, sizeof(buffer) - len, "%02X ", data[j]);
    }
    
    // 添加换行符
    snprintf(buffer + len, sizeof(buffer) - len, "\n");
    
    // 通过映射的UART端口输出（关键修改）
    UART_Type* uart = can_channel_to_uart(channel);  // 根据CAN通道获取UART
    uart_send_string(uart, buffer);  // 使用对应的UART发送
}


// 在main函数返回前添加：
void test_uart_output(UART_Type *uart, const char *name)
{
    printf("Testing %s output...\n", name);
    const char *test_msg = "UART self-test message\n";
    uart_send_string(uart, test_msg);
    board_delay_ms(100); // 等待发送完成
}


// 主函数
int main(void)
{

    buff_index = 0;   // 缓冲区索引初始化
    uint8_t cmd = 0;  // SPI 命令变量
    
    board_init_clock();
    board_init_console1();
    board_init_pmp();




    const uint8_t can_channels[] = {0, 3, 4, 6};  // 需要初始化的通道列表
    const uint8_t num_channels = sizeof(can_channels) / sizeof(can_channels[0]);
    
    // 为每个通道分配配置结构
    can_channel_config_t chan_cfgs[num_channels];
    
    #if USE_CANFD
        printf("Initializing CANFD mode\n");
        // CANFD初始化
        for (int i = 0; i < num_channels; i++) {
            uint8_t channel = can_channels[i];
            can_info_t *info = &s_can_info[channel];
            
            // 硬件初始化
            board_init_can(info->can_base);
            info->clock_freq = board_init_can_clock(info->can_base);
            
            // 初始化CANFD通道
            hpm_stat_t status = board_init_canfd(info->can_base);
            if (status != status_success) {
                printf("CANFD%d initialization failed, error code: %d\n", channel, status);
            } else {
                printf("CANFD%d initialized successfully\n", channel);
            }
        }
    #else
        printf("Initializing Classic CAN mode\n");
        // 经典CAN初始化
        for (int i = 0; i < num_channels; i++) {
            uint8_t channel = can_channels[i];
            can_info_t *info = &s_can_info[channel];
            
            // 硬件初始化
            board_init_can(info->can_base);
            info->clock_freq = board_init_can_clock(info->can_base);
            
            // 设置通道配置
            chan_cfgs[i].channel = channel;
            chan_cfgs[i].base = (MCAN_Type *)info->can_base;
            
            // 初始化通道
            hpm_stat_t status = init_can_channel(&chan_cfgs[i], info->clock_freq);
            if (status != status_success) {
                printf("CAN%d initialization failed, error code: %d\n", channel,
                
                
                
                 status);
            } else {
                printf("CAN%d initialized successfully\n", channel);
            }
        }
    #endif


    /* 仅启用通道4的中断 */
    intc_m_enable_irq_with_priority(IRQn_MCAN4, 1);
    intc_m_enable_irq_with_priority(IRQn_MCAN6, 1);
    intc_m_enable_irq_with_priority(IRQn_MCAN0, 1);
    intc_m_enable_irq_with_priority(IRQn_MCAN3, 1);

    
 
    // 初始化调用
    init_uart(TEST_UART2, TEST_UART2_CLK_NAME);
    init_uart(TEST_UART5, TEST_UART5_CLK_NAME);
    init_uart(TEST_UART4, TEST_UART4_CLK_NAME);
    init_uart(TEST_UART7, TEST_UART7_CLK_NAME);



        uart_enable_irq(TEST_UART2, uart_intr_rx_data_avail_or_timeout);  // 启用 RX 数据可用或超时中断
    intc_m_enable_irq_with_priority(TEST_UART2_IRQ, 1);  // 启用 UART 中断（优先级1）

        uart_enable_irq(TEST_UART5, uart_intr_rx_data_avail_or_timeout);  // 启用 RX 数据可用或超时中断
    intc_m_enable_irq_with_priority(TEST_UART5_IRQ, 1);  // 启用 UART 中断（优先级1） 
        uart_enable_irq(TEST_UART4, uart_intr_rx_data_avail_or_timeout);  // 启用 RX 数据可用或超时中断
    intc_m_enable_irq_with_priority(TEST_UART4_IRQ, 1);  // 启用 UART 中断（优先级1） 
        uart_enable_irq(TEST_UART7, uart_intr_rx_data_avail_or_timeout);  // 启用 RX 数据可用或超时中断
    intc_m_enable_irq_with_priority(TEST_UART7_IRQ, 1);  // 启用 UART 中断（优先级1）


        // 测试所有UART输出
    //test_uart_output(HPM_UART2, "UART2");
    //test_uart_output(HPM_UART4, "UART4");
    //test_uart_output(HPM_UART7, "UART7");
    test_uart_output(HPM_UART5, "UART5");
    return 0;  // 主函数返回（实际不会执行到这里）
}